/**
 * 
 */
package edu.ou.cs.youming;

import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;

import edu.ou.cs.youming.agents.HeuristicAgent;
import edu.ou.cs.youming.jaxb.types.Dictionary;
import edu.ou.cs.youming.jaxb.types.Example;
import edu.ou.cs.youming.jaxb.types.Feature;
import edu.ou.cs.youming.jaxb.types.Label;
import edu.ou.cs.youming.services.DataIO;
import edu.ou.cs.youming.services.Services;

/**
 * @author Youming Lin
 * 
 */
public class HeuristicMain {
	static final String corpusPath = "D:/Cruzer USB/Fall 2012/CS 5033/Project/corpus.csv";
	static final String dir = "D:/Cruzer USB/Fall 2012/CS 5033/Project/rawdata/";

	/**
	 * @param args
	 * @throws Exception
	 */
	public static void main(final String[] args) throws Exception {
		// create results directory for saving accuracy results
		final File folder = new File("results");
		folder.mkdir();
		final PrintWriter out = new PrintWriter(new FileWriter(folder.getAbsolutePath()
				+ File.separator + "heuristic.csv"));

		// /////////////////////////////////////////////////////////////////////////////
		// parse data set
		final long startTime = System.nanoTime();
		ArrayList<Example> examples = (ArrayList<Example>) DataIO.parseExamples(
				corpusPath, dir);
		final long endTime = System.nanoTime();

		System.out.println("Parsing " + examples.size() + " examples took "
				+ (endTime - startTime) / 1000000000.0 + "s.");

		for (final Iterator<Example> itr = examples.iterator(); itr.hasNext();) {
			switch (itr.next().polarity) {
				case POSITIVE:
					break;
				case NEGATIVE:
					break;
				default:
					itr.remove();
					break;
			}
		}

		System.out.println("Total positive/negative examples: " + examples.size());

		examples = (ArrayList<Example>) Services.processTweets(examples);
		final Dictionary dict = Services.buildDictionary(examples);
		final Map<Feature, Label> features = Services.generateFeatures(examples);

		// ////////////////////////////////////////////////////////////////////////////
		// predict label based on sum of each tweet's word sentiment values
		final Random random = new Random(System.nanoTime());
		out.println("Threshold, Dictionary Size, Polarity, Total, Correct Predictions, Accuracy");

		for (double threshold = 0d; threshold < 20d; ++threshold) {
			int totalPos = 0;
			int totalNeg = 0;
			int posCorrect = 0;
			int negCorrect = 0;
			dict.trim(threshold);
			final HeuristicAgent agent = new HeuristicAgent();
			agent.train(features, dict);

			for (final Entry<Feature, Label> e : features.entrySet()) {
				final Label prediction = agent.predict(e.getKey());

				switch (prediction) {
					case POSITIVE:
						switch (e.getValue()) {
							case POSITIVE:
								++totalPos;
								++posCorrect;
								break;
							case NEGATIVE:
								++totalNeg;
								break;
							default:
								throw new Exception("Unsupported label: " + e.getValue()
										+ " Tweet id: " + e.getKey().id);
						}
						break;
					case NEGATIVE:
						switch (e.getValue()) {
							case POSITIVE:
								++totalPos;
								break;
							case NEGATIVE:
								++totalNeg;
								++negCorrect;
								break;
							default:
								throw new Exception("Unsupported label: " + e.getValue()
										+ " Tweet id: " + e.getKey().id);
						}
						break;
					default:
						throw new Exception("Unsupported label: " + e.getValue()
								+ " Tweet id: " + e.getKey().id);
				}
			}

			out.println(threshold + ", " + dict.sentimentValues.size() + ", "
					+ Label.POSITIVE + ", " + totalPos + ", " + posCorrect + ", "
					+ (double) posCorrect / (double) totalPos * 100.0);
			out.println(threshold + ", " + dict.sentimentValues.size() + ", "
					+ Label.NEGATIVE + ", " + totalNeg + ", " + negCorrect + ", "
					+ (double) negCorrect / (double) totalNeg * 100.0);
		}

		out.close();
		System.out.println("Done");
		System.out.println(dict.toString());
	}
}